#include "String.h"

size_t GetAllocateLen( size_t len )
{
	int cnt = len / default_alloc_len + 1;
	return cnt * default_alloc_len;
}


String::String()
{
	cap = default_alloc_len;
	wstr = new WCHAR[ cap ];
	wsprintf( wstr, L"" );

	len = 1;
}

String::String( const String& str )
{
	len = str.size();
	cap = GetAllocateLen( len + 1);
	wstr = new WCHAR[ cap ];
	wsprintf( wstr, str.wstr );
}

String::String( const WCHAR* str )
{
	len = wcslen( str );
	cap = GetAllocateLen( len + 1 );
	wstr = new WCHAR[ cap ];
	wsprintf( wstr, str );
}

String::String( const string& str )
{
	int nChars = MultiByteToWideChar( CP_ACP, 0, str.c_str(), -1, NULL, 0 );
	cap = GetAllocateLen( nChars + 1 );
	len = nChars ;
	wstr = new WCHAR[ cap ];
	MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, (LPWSTR)wstr, nChars);
}

String::String( size_t n )
{
	len = n;
	cap = GetAllocateLen( len + 1 );
	wstr = new WCHAR[ cap ];
}

String::~String()
{
	delete [] wstr;
}

size_t String::size() const
{
	return len;
}

const WCHAR* String::wc_str() const
{
	return wstr;
}

String String::subStr( int i, int j )
{
	String str( j - i + 1 + 1 );
	for ( int id = i; id != j; ++id ) {
		str[ id ] = wstr[ id ];
	}
	str[ j ] = NULL;
	return str;
}

String::operator WCHAR*()
{
	return wstr;
}

String& String::operator+=( String& str )
{
	len = len + str.size();
	if ( cap < len ) {
		cap = GetAllocateLen( len + 1 );
		delete [] wstr;
		wstr = new WCHAR[ cap ];
	}
	wcscat( wstr, str.wc_str() );
	return *this;
}

String& String::operator+=( WCHAR* str )
{
	len = len + wcslen( str );
	if ( cap < len ) {
		cap = GetAllocateLen( len + 1 );
		delete [] wstr;
		wstr = new WCHAR[ cap ];
	}
	wcscat( wstr, str );
	return *this;
}

String& String::operator=( String& str )
{
	if(this == &str)return *this;
	len = str.size();
	cap = GetAllocateLen( len + 1 );
	WCHAR* temp = wstr;
	wstr = new WCHAR[ cap ];
	wsprintf( wstr, str.wstr );
	delete temp;
	return *this;
}

String& String::operator=( WCHAR* str )
{
	len = wcslen( str );
	cap = GetAllocateLen( len + 1 );
	WCHAR* temp = wstr;
	wstr = new WCHAR[ cap ];
	wsprintf( wstr, str );
	delete temp;
	return *this;	
}

WCHAR& String::operator[]( int i )
{
	return wstr[ i ];
}
const WCHAR& String::operator[]( int i ) const
{
	return (*this)[ i ];
}

String operator+( String& lstr, String& rstr )
{
	String temp = lstr;
	return temp+=rstr;
}

String operator+( String& lstr, WCHAR* rstr )
{
	String temp = lstr;
	return temp+=rstr;
}

String operator+( WCHAR* lstr, String& rstr )
{
	String temp( lstr );
	return temp+=rstr;
}

bool operator==( String& lstr, String& rstr )
{
	if ( wcscmp( lstr.wstr, rstr.wstr ) != 0 )
		return false;
	return true;
}

bool operator==( String& lstr, WCHAR* rstr )
{
	if ( wcscmp( lstr.wstr, rstr ) != 0 )
		return false;
	return true;
}

bool operator==( WCHAR* lstr, String& rstr )
{
	if ( wcscmp( lstr, rstr.wstr ) != 0 )
		return false;
	return true;
}

bool operator!=( String& lstr, String& rstr )
{
	return !( lstr == rstr );
}

bool operator!=( String& lstr, WCHAR*  rstr )
{
	return !( lstr == rstr );
}

bool operator!=( WCHAR*  lstr, String& rstr )
{
	return !( lstr == rstr );
}

